<?php
namespace App\Common;

use App\Common\Lib\Email;
use App\Common\Lib\SendEmail;
use App\Service\ErrorPoliceService;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Utils\ApplicationContext;

/**
 * 错误处理辅助类
 */

class MyErrorHandler {

    public $error_level = '用户级别错误';

    public function __construct() {
        //https://www.php.net/manual/zh/function.set-error-handler.php
        //https://www.php.net/manual/zh/function.register-shutdown-function.php

        // 注册错误处理
        set_error_handler(array($this, 'handleError'));

        // 注册致命错误时的处理
        //register_shutdown_function(array($this, 'handleFatalPHPError'));
    }

    /**
     * 自定义的错误处理函数
     * @param int $errno 包含了错误的级别，是一个 integer
     * @param string $errstr 包含了错误的信息，是一个 string
     * @param string $errfile 可选的，包含了发生错误的文件名，是一个 string
     * @param int $errline 可选项，包含了错误发生的行号，是一个 integer
     * @link https://www.php.net/manual/zh/function.set-error-handler.php
     */
    public function handleError($error_no, $error_msg, $error_file, $error_line) {
        $container = ApplicationContext::getContainer();
        $request = $container->get(RequestInterface::class);

        $method = $request->getMethod();
        $action = $request->getRequestUri();
        $url = $request->url();
        $params = $request->all();

        $error = "";
        $error .= 'method => '.$method."<br>";
        $error .= 'action => '.$action."<br>";
        $error .= 'url => '.$url."<br>";
        $error .= 'params => '.json_encode($params, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)."<br>";
        $error .= '错误级别 => '.$this->error_level."<br>";
        $error .= '错误编号 => '.$error_no."<br>";
        $error .= '错误信息 => '.$error_msg."<br>";
        $error .= '错误文件 => '.$error_file."<br>";
        $error .= '错误行号 => '.$error_line."<br>";
        zlog('error', $error);
        var_dump($error);
        $appEnv = env('APP_ENV');
        $emailPolice = env('EMAIL_POLICE', 'false');
        if (in_array($appEnv, ['local', 'dev']) && $emailPolice == true ) {
            $to = ['1085562810@qq.com'];
            //$to = ['jiangyongwei@banchengyun.com', '805527587@qq.com'];
            $subject = $appEnv.'_hyperf-skeleton项目错误';
            make(ErrorPoliceService::class)->push($to, $subject, $error, 3);
            //$email = new Email();
            /*$email = new SendEmail();
            $to = ['1085562810@qq.com'];
            $subject = env('APP_ENV').'_hyperf-skeleton项目错误';
            $res = $email->send($to, $subject, $error);*/
            //var_dump($res);
        }

    }

    /**
     * 处理致命错误
     */
    public function handleFatalPHPError() {
        /* error_get_last() 函数获得最后发生的错误。
                            该函数以数组的形式返回最后发生的错误。如果没有错误发生则返回 NULL。
                            返回的错误数组包含 4 个键名和键值：
        [type] - 错误类型
        [message] - 错误消息
        [file] - 发生错误所在的文件
        [line] - 发生错误所在的行
        */
        $last_error = error_get_last();
        if ($last_error) {
            $this->error_level = '程序致命错误';
            $this->handleError($last_error['type'], $last_error['message'], $last_error['file'], $last_error['line']);
        }
    }

}